
import * as 引擎 from "./translator"
import { 编辑器_, 同步输出结果_, 异步输出_, _Charas_ } from "../ctsEnumsAndTypes/enumsAndTypes";
import { 字符是字母, 字符是单行空白, 驼峰分割文本 } from "../ctsUtils/utils";

function 创建编辑器(): 编辑器_ {
    let 内部内容: string = "";
    function 写出(内容: string) {
        内部内容 += 内容;
    }

    function 取插入位置(): number {
        return 内部内容.length;

    }
    function 取输出文本(): string {
        return 内部内容;

    }
    function 复位() {
        内部内容 = "";
    }

    return {
        写出,
        取插入位置,
        取输出文本,
        复位
    }

}

function 异步翻译文本(注释内容: string): 同步输出结果_ {

    let 编辑器 = 创建编辑器();
    编辑器.复位();

    let 异步内容: 异步输出_[] = [];

    let 文本组 = 扫描().扫描分组(注释内容);

    let 前方方括号左 = false;
    let 开始网址链接 = false;

    for (let i = 0; i < 文本组.length; i++) {
        let v = 文本组[i]
        switch (v.属性) {
            case 文本属性.是方括号左:
                前方方括号左 = true;
                编辑器.写出(v.文本);
                break;
            case 文本属性.是方括号右:
                let v2 = 文本组[i + 1];
                if (前方方括号左 && v2 && v2.属性 === 文本属性.是圆括号左) {
                    前方方括号左 = false;
                    开始网址链接 = true;
                }
                编辑器.写出(v.文本);
                break;
            case 文本属性.是圆括号左:
                if (开始网址链接) {
                    while (i < 文本组.length) {
                        let v2 = 文本组[i];
                        if (v2.属性 === 文本属性.是圆括号右) {
                            开始网址链接 = false;
                            编辑器.写出(v2.文本);
                            break;
                        }
                        编辑器.写出(v2.文本);
                        i++;
                    }
                    break;
                } else {
                    编辑器.写出(v.文本);
                }
                break;
            case 文本属性.是三点号:
                let 开头 = true;
                while (i < 文本组.length) {
                    let v2 = 文本组[i];
                    if (v2.属性 === 文本属性.是三点号 && !开头) {
                        编辑器.写出(v2.文本);
                        break;
                    }
                    开头 = false;
                    编辑器.写出(v2.文本);
                    i++;
                }

                break;
            case 文本属性.是字母:
                let 输出翻译 = "";
                while (i < 文本组.length) {
                    let v2 = 文本组[i];
                    if (v2.属性 !== 文本属性.是字母 && v2.属性 !== 文本属性.是单空格) {
                        i--;
                        break;
                    }
                    输出翻译 += v2.文本;
                    i++;
                }
                异步内容.push({ 插入位置: 编辑器.取插入位置(), 插入内容: 输出翻译 });
                break;
            default:
                编辑器.写出(v.文本);
                break;

        }

    }

    return {

        同步输出结果: 编辑器.取输出文本(),
        异步输出数组: 异步内容

    };

}

enum 文本属性 {
    是字母,
    是方括号左,
    是方括号右,
    是圆括号左,
    是圆括号右,
    是三点号,
    是单空格,
    是其他
}

interface 文本 {
    文本: string;
    属性: 文本属性;
}

function 扫描() {

    let 当前文本: string;
    let pos: number;
    let end: number;
    let str: number;

    function 扫描分组(文本: string) {
        当前文本 = 文本;
        end = 当前文本.length;
        pos = 0;
        str = 0;
        return 取文本组();
    }

    function 取字符(增加?: number) {
        增加 = 增加 || 0;
        if (pos + 增加 < end) {
            return 当前文本.charCodeAt(pos += 增加);
        }
        else {
            return -1;
        }
    }

    function 前进(步幅?: number) {
        步幅 = 步幅 || 1;
        if (pos + 步幅 < end) {
            pos += 步幅;
        }
        else {
            pos = end;
        }
    }

    function 取文本() {
        let 返回值 = 当前文本.substring(str, pos);
        str = pos;
        return 返回值;
    }

    function 取文本组() {

        if (当前文本 === null) {
            return [];
        }

        let ch: number;
        let 临时集: 文本[] = [];

        while (true) {

            ch = 取字符();

            if (pos > end || ch === -1) {
                break;
            }

            if (字符是字母(ch)) {

                while (字符是字母(ch)) {
                    前进();
                    ch = 取字符();
                }

                临时集.push({ 文本: 取文本(), 属性: 文本属性.是字母 });

            }
            else if (字符是单行空白(ch)) {

                while (字符是单行空白(ch)) {
                    前进();
                    ch = 取字符();
                }

                let 文本 = 取文本();

                if (文本 === " ") {
                    临时集.push({ 文本, 属性: 文本属性.是单空格 });

                }
                else {
                    临时集.push({ 文本, 属性: 文本属性.是其他 });

                }

            }
            else if (ch === _Charas_.openBracket) {
                前进();
                临时集.push({ 文本: 取文本(), 属性: 文本属性.是方括号左 });

            }
            else if (ch === _Charas_.openParen) {
                前进();
                临时集.push({ 文本: 取文本(), 属性: 文本属性.是圆括号左 });

            }
            else if (ch === _Charas_.closeBracket) {
                前进();
                临时集.push({ 文本: 取文本(), 属性: 文本属性.是方括号右 });

            }
            else if (ch === _Charas_.closeParen) {
                前进();
                临时集.push({ 文本: 取文本(), 属性: 文本属性.是圆括号右 });

            }
            else if (ch === _Charas_.backtick) {

                while (ch === _Charas_.backtick) {
                    前进();
                    ch = 取字符();
                }

                let 文本 = 取文本();

                if (文本.length === 3) {
                    临时集.push({ 文本, 属性: 文本属性.是三点号 });
                }
                else {
                    临时集.push({ 文本, 属性: 文本属性.是其他 });
                }

            }
            else {

                while (!字符是字母(ch) && !字符是单行空白(ch) && ch !== -1 && ch !== _Charas_.openBracket && ch !== _Charas_.openParen && ch !== _Charas_.closeBracket && ch !== _Charas_.closeParen && ch !== _Charas_.backtick) {
                    前进();
                    ch = 取字符();
                }

                临时集.push({ 文本: 取文本(), 属性: 文本属性.是其他 });

            }

        }
        return 临时集;
    }

    return {
        扫描分组,
    }

}

export async function 翻译注释文本(注释内容: string) {

    const 翻译结果 = 异步翻译文本(注释内容);

    let 输出文本 = 翻译结果.同步输出结果;
    const 异步内容 = 翻译结果.异步输出数组;

    let 累计 = 0;

    if (异步内容.length > 0) {
        let 输出 = "";
        for (let 合并内容 of 异步内容) {
            if (合并内容 && 合并内容.插入内容) {
                let 插入值 = 合并内容.不翻译 ? 合并内容.插入内容 : await 翻译(合并内容.插入内容)
                输出 += 输出文本.substring(累计, 合并内容.插入位置) + 插入值;
                累计 = 合并内容.插入位置;
            }
        }

        输出文本 = 输出 + 输出文本.substring(累计);
    }

    return 输出文本;

}

async function 翻译(文本: string) {

    let 数组 = 驼峰分割文本(文本);
    let 去空 = 数组.filter(v => !!v.trim());

    if (去空 && 去空.length) {
        let 翻译值 = await 翻译普通文本(去空.join(" "));
        翻译值 = 翻译值.replace(/(,|。|，)/g, "");
        return 翻译值;
    }

    return 文本;

}

async function 翻译普通文本(文本: string) {

    let 返回结果 = "";
    let 翻译结果 = await 引擎.翻译器!(文本);

    if (翻译结果) {

        if (引擎.是有道错误(翻译结果) || 引擎.是百度错误(翻译结果)) {
            //什么也不做
        }
        else if (引擎.是百度结果(翻译结果)) {

            if (翻译结果.trans_result && 翻译结果.trans_result[0]) {
                返回结果 += 翻译结果.trans_result[0].dst;

            }

        }
        else if (引擎.是有道结果(翻译结果)) {

            if (翻译结果.translation && 翻译结果.translation[0]) {
                返回结果 += 翻译结果.translation[0];

            }

        }

    }

    return 返回结果;

}
